package com.xmmj.baselibrary.base.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.xmmj.baselibrary.base.activity.mvvm.BaseViewModel
import com.xmmj.baselibrary.base.activity.permission.PermissionActivity
import java.lang.reflect.ParameterizedType

/**
 * 支持MVVM架构的Fragment
 */
abstract class BaseMvvmFragment<DB : ViewDataBinding, VM : BaseViewModel<*>> : BaseFragment() {
    lateinit var mDataBinding: DB
    lateinit var mViewModel: VM

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        initViewModel()
        initViewDataBinding(inflater, container)
        observeLiveData()
        return mDataBinding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mDataBinding.unbind()
    }

    /**
     * 初始化ViewModel
     */
    private fun initViewModel() {

        val type = this.javaClass.genericSuperclass
        val modelClass: Class<*> = if (type is ParameterizedType) {
            val modelClassList = type.actualTypeArguments
            if (modelClassList.size > 1) {
                modelClassList[1] as Class<*>
            } else if (modelClassList.size == 1) {
                modelClassList[0] as Class<*>
            } else {
                BaseViewModel::class.java
            }
        } else {
            BaseViewModel::class.java
        }
        //创建ViewModel
        mViewModel = createViewModel<ViewModel>(requireActivity(), modelClass) as VM
        //添加观察者
        mViewModel.let { lifecycle.addObserver(it) }
        //注册被观察者
        mViewModel.lifecycleOwner = this

    }

    /**
     * 初始化DataBinding
     */
    private fun initViewDataBinding(inflater: LayoutInflater, parent: ViewGroup?) {
        mDataBinding = DataBindingUtil.inflate(inflater, getContentViewId(), parent, false)
        //注册被观察者
        mDataBinding.lifecycleOwner = this
        //绑定ViewModel
        mDataBinding.setVariable(getVariableId(), mViewModel)
    }

    /**
     * 观察基础UI事件
     */
    private fun observeLiveData() {
        mViewModel.showLoadingLiveData!!.observe(requireActivity()) { showLoading(it) }
        mViewModel.hideLoadingLiveData!!.observe(requireActivity()) { hideLoading() }
        mViewModel.toastLiveData!!.observe(requireActivity()) { toast(it) }
        mViewModel.reLoginLiveData!!.observe(requireActivity()) { onReLogin() }
        mViewModel.finishLiveData!!.observe(requireActivity()) { requireActivity().finish() }
        mViewModel.finishRefreshLiveData!!.observe(requireActivity()) { finishRefresh() }
        mViewModel.finishLoadMoreLiveData!!.observe(requireActivity()) { finishLoadMore(it) }
        mViewModel.requestLiveData!!.observe(requireActivity()) {
            onRequest()
            onLazyLoad()
        }
        mViewModel.setResultLiveData!!.observe(requireActivity()) {
            requireActivity().setResult(it.resultCode, it.data)
        }
        mViewModel.showEmptyLiveData!!.observe(requireActivity()) {
            showEmpty(it.isShow, it.imageId, it.hintText)
        }
        mViewModel.showErrorLiveData!!.observe(requireActivity()) {
            showError(it.imageId, it.errorText, it.btnText)
        }
        mViewModel.setFragmentLiveData!!.observe(requireActivity()) {
            setCurrentFragment(it.id, it.fragment)
        }
        mViewModel.requestPermissionLiveData!!.observe(requireActivity()) {
            if (requireActivity() is PermissionActivity) {
                (requireActivity() as PermissionActivity).requestPermission(
                    it.permissions,
                    it.successAction,
                    it.cancelAction,
                    it.description
                )
            }
        }
    }

    /**
     * 创建ViewModel
     *
     * @param activity 上下文
     * @param cls      类
     */
    private fun <T : ViewModel?> createViewModel(activity: FragmentActivity, cls: Class<*>): T {
        return ViewModelProvider(activity).get(this.toString(), cls as Class<T>)
    }

    /**
     * 获取model变量id
     */
    abstract fun getVariableId(): Int

    /**
     * 获取布局id
     */
    abstract fun getContentViewId(): Int
}